<template>
  <div class="functional-calculation">
    <div class="functional-calculation-left" ref="functionalCalculationLeft">
      <div class="functional-calculation-left-in">
        <div class="btns" ref="mainBodyLeftHead2">
          <el-button
            type="primary"
            class="el-btn"
            size="mini"
            @click="importFile()"
          >
            <svg-icon icon-class="uploadfiles" />
            导入
          </el-button>
          <el-button
            type="primary"
            class="el-btn"
            size="mini"
            @click="deleteFile()"
            :disabled="!powderCompoundDataManageSel.length"
          >
            <svg-icon icon-class="deletefile" />
            删除
          </el-button>
        </div>

        <ul class="file-list" :style="{ height: leftFilelistHeight }">
          <li v-if="powderCompoundFileImportList.length">
            <div
              :class="[
                'file-check-box',
                isFilesListSelectAll ? 'file-check-box-checked' : '',
              ]"
              @click="filesListSelectAll()"
            >
              <svg-icon icon-class="check3" v-if="isFilesListSelectAll" />
            </div>
            <div class="file-list-select-txt">全选</div>
          </li>
          <li v-for="(item, key) in powderCompoundFileImportList" :key="key">
            <div
              :class="[
                'file-check-box',
                powderCompoundDataManageSel.includes(item)
                  ? 'file-check-box-checked'
                  : '',
              ]"
              @click="powderCompoundCheckfile(item)"
            >
              <svg-icon
                icon-class="check3"
                v-if="powderCompoundDataManageSel.includes(item)"
              />
            </div>
            <div class="file-body">
              {{ item }}
            </div>
          </li>
        </ul>
      </div>
    </div>
    <div class="functional-calculation-center">
      <div class="btns" ref="functionalCalculationCenterHead">
        <el-button
          type="primary"
          class="el-btn2"
          size="mini"
          :disabled="!powderCompoundDataManageSel.length"
          @click="drawChart()"
        >
          <svg-icon icon-class="drawchart" />
          绘制图表
        </el-button>
        <el-input
          v-model="y_value"
          size="mini"
          clearable
          @input="(e) => handleEdit(e, 'y_value')"
          class="horizontal-val"
        />
        <el-button
          type="primary"
          class="el-btn2"
          size="mini"
          :disabled="!(powderCompoundDataManageSel.length && y_value)"
          @click="drawhorizontalLine()"
        >
          <svg-icon icon-class="drawline" />
          绘制横线
        </el-button>
        <el-button
          type="warning"
          class="el-btn el-btn-noicon"
          size="mini"
          :disabled="!powderCompoundDataManageSel.length"
          @click="formatChart()"
        >
          初始化
        </el-button>
      </div>
      <div
        id="chart"
        ref="powderCompoundChart"
        class="chart"
        :style="{ width: chartWidth, height: chartHeight }"
      ></div>
    </div>
    <div class="functional-calculation-right" ref="functionalCalculationRight">
      <div class="functional-calculation-right-in">
        <div
          ref="functionalCalculationRightTop"
          class="functional-calculation-right-top"
        >
          <div class="functional-calculation-right-top-in">
            <div class="btns-select-all">
              <div class="btns">
                <el-button
                  type="primary"
                  class="el-btn el-white-btn"
                  size="mini"
                  @click="selectall()"
                >
                  <svg-icon icon-class="selectall" />
                  全选
                </el-button>
                <el-button
                  type="primary"
                  class="el-btn el-white-btn"
                  size="mini"
                  @click="clearall()"
                >
                  <svg-icon icon-class="clearselect" />
                  清空选择
                </el-button>
              </div>
              <el-tooltip class="tips" effect="dark" placement="bottom-end">
                <div slot="content">
                  <ul class="tips-content">
                    <li>点的选取原则：</li>
                    <li>1.当您有了n种材料时，应当选择n+1个计算点；</li>
                    <li>
                      2.计算点的选择应当符合规则：基线与最小材料交点、最小材料与大一级材料交点、大一级材料与最大材料交点、最大材料交点与基线交点；
                    </li>
                    <li>3.请尽可能确保材料之间的交点处于基线以上。</li>
                    <li><div class="tips-bold">基线的选取原则：</div></li>
                    <li>按经验进行基线选择，常用值为1。</li>
                    <li><div class="tips-bold">幂指数的选取原则：</div></li>
                    <li>
                      按dinger-funk理论，幂指数的取值应当介于0-1之间，幂指数取值越小代表复配体系理论上越密集，常用值为0.37。
                    </li>
                  </ul>
                </div>
                <div class="questionmark">
                  <svg-icon icon-class="questionmark" />
                </div>
              </el-tooltip>
            </div>
            <ul class="dot-intersection-list">
              <li
                v-for="(item, key) in allintersectiondot"
                :key="key"
                @click="chooseIntersectionDot(key)"
              >
                <div
                  :class="[
                    'file-check-box',
                    compouteIntersection(key) ? 'file-check-box-checked' : '',
                  ]"
                >
                  <svg-icon
                    icon-class="check3"
                    v-if="compouteIntersection(key)"
                  />
                </div>
                <div class="txt">点{{ key + 1 }}</div>
                <div class="txt">x={{ computeRound(item[0]) }}</div>
                <div class="txt">y={{ computeRound(item[1]) }}</div>
              </li>
            </ul>
            <div class="btns-compute">
              <el-input
                v-model="m_value"
                size="mini"
                clearable
                @input="(e) => handleEdit(e, 'm_value')"
              />
              <el-button
                type="primary"
                class="el-btn"
                size="mini"
                @click="computePoint()"
                :disabled="computePointdisable"
              >
                开始计算
              </el-button>
            </div>
          </div>
        </div>

        <div
          class="compute-model"
          ref="computeModel"
          :style="{ height: computeModelHeight }"
        >
          <ul class="cross-dot-val">
            <li>{{ intersectionVals.length ? "交点计算值" : "" }}</li>
            <li
              v-for="(item, key) in intersectionVals"
              :key="'intersectionVals' + key"
            >
              点{{ key + 1 }}: X={{ computeRound(item.x) }}, Y={{
                computeRound(item.y)
              }}, 值={{ computeRound(item.value, 5) }}
            </li>
            <li v-if="deltas.length">计算结果:</li>
            <el-table
              :data="deltas"
              v-if="deltas.length"
              class="deltas-table"
              style="width: 100%"
            >
              <el-table-column prop="name" label="材料"> </el-table-column>
              <el-table-column prop="v" label="体积"
                ><template slot-scope="scope">{{
                  computeRound(scope.row.v, 5)
                }}</template>
              </el-table-column>
              <el-table-column prop="m" label="质量"
                ><template slot-scope="scope">{{
                  computeRound(scope.row.m, 5)
                }}</template></el-table-column
              >
            </el-table>
          </ul>
        </div>
      </div>
    </div>
    <property-dialog
      :showPropertyDialog.sync="showPropertyDialog"
      :propertyList.sync="propertyList"
      @sentPropertyData="sentPropertyData"
    ></property-dialog>
  </div>
</template>

<script>
import {
  get_files,
  upload,
  get_detile,
  curve_intersections,
  horizontal_intersections,
  points,
  merge,
  rename,
  dataManageDel,
  get_config_parameters,
  densest_accumulation_all,
} from "@/api/index";
import { deepClone, computeRound } from "@/utils";
import propertyDialog from "@/components/propertyDialog";
export default {
  name: "HelloWorld",
  props: {
    user_name: {
      type: String,
      default: "",
    },
    leftFilelistHeight: {
      type: String,
      default: "",
    },
    user_id: {
      type: String,
      default: "",
    },
    computeModelHeight: {
      type: String,
      default: "",
    },
    computeDotHeight: {
      type: String,
      default: "",
    },
    chartHeight: {
      type: String,
      default: "",
    },
    chartWidth: {
      type: String,
      default: "",
    },
    powderCompoundFileImportList: {
      type: Array,
      default: () => [],
    },
  },
  components: {
    propertyDialog,
  },
  computed: {
    compouteIntersection() {
      return (item) => {
        return (
          this.selectIntersectionDot.findIndex((iitem) => iitem === item) > -1
        );
      };
    },
    computeRound() {
      return (val, num) => {
        let n = 4;
        if (num) {
          n = num;
        }
        return (Math.round(val * Math.pow(10, n)) / Math.pow(10, n)).toFixed(n);
      };
    },
    computePointdisable() {
      return (
        this.selectIntersectionDot.length !==
        this.powderCompoundDataManageSel.length + 1
      );
    },
  },
  data() {
    return {
      showPropertyDialog: false,
      propertyList: [],
      isFilesListSelectAll: false,
      myChart: null,
      y_value: 0.5,
      m_value: 0.37,
      horizontaldot: [],
      intersectiondot: [],
      allintersectiondot: [],
      selectIntersectionDot: [],
      powderCompoundDataManageSel: [],
      intersectionVals: [],
      chartData: [],
      drawChartClick: false,
      deltas: [],
    };
  },
  watch: {
    chartWidth: {
      immediate: true,
      handler(val) {
        this.$nextTick(() => {
          if (this.myChart) this.myChart.resize();
        });
      },
    },
    chartHeight: {
      immediate: true,
      handler(val) {
        this.$nextTick(() => {
          if (this.myChart) this.myChart.resize();
        });
      },
    },
  },
  methods: {
    selectall() {
      this.selectIntersectionDot = this.allintersectiondot.map((_, key) => key);
    },
    clearall() {
      this.selectIntersectionDot = [];
    },
    filesListSelectAll() {
      if (this.isFilesListSelectAll) {
        this.isFilesListSelectAll = false;
        this.powderCompoundDataManageSel = [];
      } else {
        this.isFilesListSelectAll = true;
        this.powderCompoundDataManageSel = deepClone(
          this.powderCompoundFileImportList
        );
      }
    },
    handleEdit(e, type) {
      let value = e.replace(/[^\d.]/g, "").replace(/\.{2,}/g, ".");
      this[type] = value;
    },
    importFile() {
      this.$emit(
        "showFilesListDialog",
        "powderCompound",
        deepClone(this.powderCompoundFileImportList)
      );
    },
    chooseIntersectionDot(item, isNotDel) {
      let index = this.selectIntersectionDot.findIndex(
        (iitem) => iitem === item
      );

      if (index > -1) {
        if (!isNotDel) {
          this.selectIntersectionDot.splice(index, 1);
        }
      } else {
        this.selectIntersectionDot.push(item);
      }
    },
    async computePoint() {
      if (!this.selectIntersectionDot.length) {
        this.$message({
          type: "error",
          message: "请选择交点",
        });
        return;
      }

      let powderCompoundDataManageSelLength =
        this.powderCompoundDataManageSel.length;
      if (powderCompoundDataManageSelLength) {
        if (
          this.selectIntersectionDot.length !==
          powderCompoundDataManageSelLength + 1
        ) {
          this.$message({
            type: "error",
            message:
              "您当前绘制了" +
              powderCompoundDataManageSelLength +
              "个材料，请选择" +
              (powderCompoundDataManageSelLength + 1) +
              "个交点",
          });
          return;
        }
      }
      this.showPropertyDialog = true;

      this.propertyList = this.powderCompoundDataManageSel.map((e) => {
        return { name: e, density: "" };
      });
    },
    async sentPropertyData(data) {
      let selected_points = this.allintersectiondot.filter((_, i) =>
        this.selectIntersectionDot.includes(i)
      ).map(item=>{ return item.slice(0,3) });
      let weight_infos = {};
      data.forEach((item) => {
        weight_infos[item.name] = Number(item.density);
      });

      let res = await points({
        selected_points,
        m_value: this.m_value,
        weight_infos,
        user_name: this.user_name,
      });
      this.intersectionVals = res["results"];
      let keys = Object.keys(res["deltas"]);
      let deltas = [],
        origin_deltas = res["deltas"];
      for (let i = 0; i < keys.length; i++) {
        deltas = [
          ...deltas,
          {
            name: keys[i],
            v: origin_deltas[keys[i]][0],
            m: origin_deltas[keys[i]][1],
          },
        ];
      }
      this.deltas = deltas;
    },
    deleteFile() {
      let powderCompoundFileImportList =
        this.powderCompoundFileImportList.filter(
          (item, index) => !this.powderCompoundDataManageSel.includes(item)
        );
      this.$emit(
        "update:powderCompoundFileImportList",
        powderCompoundFileImportList
      );
      this.powderCompoundDataManageSel = [];
      this.cleardata();
    },
    async powderCompoundCheckfile(item) {
      let _index = this.powderCompoundDataManageSel.indexOf(item);
      if (_index > -1) {
        this.powderCompoundDataManageSel.splice(_index, 1);
      } else {
        this.powderCompoundDataManageSel.push(item);
      }
      this.cleardata();
    },
    async curve_intersections() {
      return new Promise(async (resolve, reject) => {
        let powderCompoundSelectFile = this.powderCompoundDataManageSel;
        let res = await curve_intersections({
          filenames: powderCompoundSelectFile,
          user_id: this.user_id,
          user_name: this.user_name,
        });
        resolve(res);
      });
    },
    async horizontal_intersections() {
      if (this.addLine && this.y_value) {
        let powderCompoundSelectFile = this.powderCompoundDataManageSel;
        let res = await horizontal_intersections({
          filenames: powderCompoundSelectFile,
          user_id: this.user_id,
          user_name: this.user_name,
          y_value: this.y_value,
        });
        let _res = {};
        let intersections = res["intersections"];
        _res["intersections"] = intersections.map((item) => {
          return [...item, true];
        });
        return _res;
      } else {
        return null;
      }
    },
    formatChart() {
      this.cleardata();
      this.y_value = 0.5;
      this.m_value = 0.37;
    },
    cleardata() {
      if (this.myChart) this.myChart.clear();
      this.horizontaldot = [];
      this.intersectiondot = [];
      this.allintersectiondot = [];
      this.selectIntersectionDot = [];
      this.intersectionVals = [];
      this.propertyList = [];
      this.deltas = [];
      this.chartData = [];
      this.addLine = false;
    },

    async drawChart() {
      if (!this.powderCompoundDataManageSel.length) {
        this.$message({
          type: "error",
          message: "请选择文件",
        });
        return;
      }
      this.drawChartClick = true;

      let promises = [];

      this.powderCompoundFileImportList.map((filename, index) => {
        if (this.powderCompoundDataManageSel.includes(filename)) {
          promises = [...promises, this.get_detile_promise(filename)];
        }
      });

      promises = [
        ...promises,
        this.curve_intersections(),
        this.horizontal_intersections(),
      ];

      const results = await Promise.all(promises);

      this.chartData = [];
      for (let i = 0; i < results.length - 2; i++) {
        let data = results[i]["file_content"].map((item) => item.slice(0, 2));
        this.chartData.push(data);
      }
      console.log(results[results.length - 1], "###this.horizontaldot");
      this.intersectiondot = results[results.length - 2]["intersections"];
      this.horizontaldot = results[results.length - 1]
        ? results[results.length - 1]["intersections"]
        : [];

      this.allintersectiondot = [
        ...this.intersectiondot,
        ...this.horizontaldot,
      ];

      this.selectIntersectionDot = [];
      this.intersectionVals = [];
      this.deltas = [];
      this.propertyList = [];

      this.getchart();
    },

    async get_detile_promise(filename) {
      return new Promise(async (resolve, reject) => {
        let res = await get_detile({
          user_id: this.user_id,
          user_name: this.user_name,
          filename,
        });
        resolve(res);
      });
    },
    async drawhorizontalLine() {
      if (!this.addLine) this.addLine = true;
      if (this.chartData.length) {
        let res = await this.horizontal_intersections();
        if (res) {
          this.horizontaldot = res.intersections;
          this.allintersectiondot = [
            ...this.intersectiondot,
            ...this.horizontaldot,
          ];
        } else {
          this.allintersectiondot = [];
        }
      }

      this.selectIntersectionDot = [];
      this.intersectionVals = [];
      this.deltas = [];
      this.propertyList = [];
      this.getchart();
    },

    getchart() {
      if (!this.myChart) {
        var chartDom = this.$refs.powderCompoundChart;
        this.myChart = this.$echarts.init(chartDom);
      }
      let series = [];
      let fileNamelist = [];
      let powderCompoundSelectFile = this.powderCompoundDataManageSel;
      let lastIndex = this.intersectiondot ? this.intersectiondot.length : 0;
      for (let i = 0; i < powderCompoundSelectFile.length; i++) {
        let filename = powderCompoundSelectFile[i];

        fileNamelist = [
          ...fileNamelist,
          filename.lastIndexOf(".") > -1
            ? filename.substring(0, filename.lastIndexOf("."))
            : filename,
        ];
      }

      for (let i = 0; i < this.chartData.length; i++) {
        let item = this.chartData[i];
        series.push({
          name: fileNamelist[i],
          type: "line",
          symbol: "none",
          data: item,
        });
      }

      console.log(this.intersectiondot, "###this.intersectiondot");
      if (this.intersectiondot.length) {
        series.push({
          label: {
            show: true,
            backgroundColor: "rgba(255,255,255,0.9)",
            width: 20,
            height: 20,
            borderColor: "#e7642f",
            borderRadius: 3,
            borderWidth: 1,
            color: "#333",
            formatter: function (params) {
              return `${params.dataIndex + 1}`; // 只显示x值或自定义格式
            },
          },
          symbolSize: 0,
          itemStyle: {},
          data: this.intersectiondot,
          type: "scatter",
          z: 10,
        });
      }
      if (this.addLine) {
        if (this.horizontaldot.length) {
          series.push({
            label: {
              show: true,
              backgroundColor: "rgba(255,255,255,0.9)",
              width: 20,
              height: 20,
              borderColor: "#e7642f",
              borderRadius: 3,
              borderWidth: 1,
              color: "#333",
              formatter: function (params) {
                return `${params.dataIndex + lastIndex + 1}`; // 只显示x值或自定义格式
              },
            },
            itemStyle: {},
            symbolSize: 0,
            data: this.horizontaldot,
            type: "scatter",
            z: 10,
          });
        }
        series.push({
          type: "line",
          smooth: true,
          markLine: {
            symbol: "none",
            lineStyle: {
              color: "#ff9c40",
              type: "dashed", // 实线
            },
            label: {
              show: false,
            },
            data: [
              {
                yAxis: this.y_value, // 纵坐标的值，决定横向辅助线在y轴的位置
              },
            ],
          },
        });
      }
      this.myChart.setOption(
        {
          toolbox: {
            show: true,
            feature: {
              dataZoom: {
                yAxisIndex: "none",
              },
              restore: {
                show: true,
              },
              saveAsImage: {
                show: true,
              },
            },
          },
          tooltip: {
            show: true,
            trigger: "item",

            axisPointer: {
              type: "shadow",
            },

            textStyle: {
              fontSize: 12,
            },
            formatter: function (params) {
              if (params.componentType === "series") {
                // console.log(params.dataIndex,params, "######params")
                let data = params["data"];
                let files = data[2].split(/\/+/g);
                let filesStr =
                  "<div class='tool-tip-files'><div>材料名：</div>";
                files.forEach((item) => {
                  filesStr += `<div class='tool-tip-file'>${item}</div>`;
                });
                filesStr += `</div>`;
                let index;
                if (data[3]) {
                  index = lastIndex + params["dataIndex"] + 1;
                } else {
                  index = params["dataIndex"] + 1;
                }
                let str = `<div class='tool-tip'>
                <div>序号：${index}</div>
                <div class='tool-tip-axis-all'><div class='tool-tip-axis'>x:${computeRound(
                  data[0],
                  4
                )}</div><div class='tool-tip-axis'>y:${computeRound(
                  data[1],
                  4
                )}</div></div>
                   <div>${filesStr}</div>
                 </div>`;
                return str;
              }
            },
          },
          dataZoom: [
            {
              type: "inside",
              xAxisIndex: 0,
              start: 0,
              end: 50,
              realtime: true,
            },
            {
              xAxisIndex: 0,
              bottom: 70,
              start: 0,

              realtime: true,
            },
          ],
          legend: {
            x: "center",
            y: "bottom",
            data: fileNamelist,
          },
          grid: {
            left: "20",
            right: "20",
            bottom: "100",
            containLabel: true,
          },
          xAxis: {
            logBase: 10,
            type: "log",
            min: 0.01,
          },
          yAxis: {
            type: "value",
            name: "分布",
            interval: 1,
            min: 0,

            max: 10,
          },
          series,
        },
        true
      );

      this.myChart.on("click", (params) => {
        if (params.componentType === "series") {
          // 获取点击的数据点信息

          var data = params.data;
          let index;
          if (data[3]) {
            index = lastIndex + params["dataIndex"] + 1;
          } else {
            index = params["dataIndex"] + 1;
          }
          console.log(
            "点击的数据点信息：",
            params["dataIndex"],
            lastIndex,
            index,
            data
          );
          this.chooseIntersectionDot(index - 1, true);
        }
      });
    },
  },
};
</script>
<style lang="scss">
.tool-tip {
  .tool-tip-axis-all {
    display: flex;
    gap: 10px;
  }
}
</style>

<style src="@/assets/powder.scss" scoped lang="scss"></style>